package collection

import (
	"gitee.com/mootok/mootok/src/models"
	"gitee.com/mootok/mootok/src/storage/database"
)

type Service struct{}

// IsCollected queries whether records exist for the specified video IDs and user ID,
// and stores the results in the result array in the exact same order.
//
// Parameters:
//   - videoIds: A slice of video IDs to check for existence.
//   - actorId: The ID of the user acting this query.
//   - result: A pointer to the boolean array that will store the query results.
//
// Returns:
//   - An error if there was an error executing the database query; otherwise, nil.
func (s *Service) IsCollected(videoIds []int, actorId int, result *[]bool) error {
	var resultsMap []models.UserVideoCollectionRelation
	existsMap := make(map[int]bool)

	// Query the database to check for existing records
	err := database.Client.Model(&models.UserVideoCollectionRelation{}).
		Where(&models.UserVideoCollectionRelation{UserId: actorId}).
		Where("video_id IN ?", videoIds).
		Find(&resultsMap).Error

	if err != nil {
		return err
	}

	for _, elem := range resultsMap {
		existsMap[elem.ID] = true
	}

	// Populate the result array in the exact same order
	for index, videoID := range videoIds {
		if exists := existsMap[videoID]; exists {
			(*result)[index] = true
		} else {
			(*result)[index] = false
		}
	}
	return nil
}

func (s *Service) CountUsers(videoIds []int, results *[]int) error {
	// Create a map to store the counts
	var countsIdMap []map[string]interface{}
	counts := make(map[int]int, len(videoIds))
	// Query the database to count the occurrences of each video ID
	err := database.Client.
		Model(&models.UserVideoCollectionRelation{}).
		Where("video_id IN ?", videoIds).
		Group("video_id").
		Select("video_id, COUNT(DISTINCT user_id) as count").
		Find(&countsIdMap).Error

	if err != nil {
		return err
	}

	for _, elem := range countsIdMap {
		counts[elem["video_id"].(int)] = int(elem["count"].(int64))
	}

	// Populate the results array in the same order as videoIds
	for index, videoID := range videoIds {
		(*results)[index] = counts[videoID]
	}

	return nil
}
